﻿using Cherry.Agile.Security;
using Cherry.Agile.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security;

namespace Cherry.Agile.UI.Framework.Security
{
    public class FormTokenProvider : ITokenProvider
    {
        public IToken CreateToken(System.Security.Principal.IIdentity user, bool createPersistent)
        {
            var token = new Token(user as User);
            DateTime time;
            if (FormsAuthentication.Timeout.TotalMinutes > 30)
                time = createPersistent ? DateTime.Now.AddDays(7) : DateTime.Now.Add(FormsAuthentication.Timeout);
            else
                time = createPersistent ? DateTime.Now.AddDays(7) : DateTime.Now.AddMinutes(30);

            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
              user.Name, DateTime.Now,
              time, createPersistent, token.GetTicketString(),
              FormsAuthentication.FormsCookiePath);

            // Encrypt the ticket.
            string encTicket = FormsAuthentication.Encrypt(ticket);

            var val = token.GetTicketString();
            var cookie = FormsAuthentication.GetAuthCookie(val, createPersistent);
            cookie.Value = FormsAuthentication.Encrypt(ticket);
            if (createPersistent)
                cookie.Expires = time;

            HttpContext.Current.Response.Cookies.Set(cookie);
            HttpContext.Current.Request.Cookies.Set(cookie);

            PushVerilyStats(val);

            return token;
        }

        private void PushVerilyStats(string tokenString)
        {
            var context = HttpContext.Current;
            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName + "_v");
            cookie.Value = tokenString.MD5() + new Random().Next(1, 9);
            cookie.Domain = FormsAuthentication.CookieDomain;
            cookie.Path = FormsAuthentication.FormsCookiePath;
            context.Response.Cookies.Add(cookie);


        }

        public IToken GetCurrentToken()
        {
            if (HttpContext.Current.Session == null)
                throw new System.Security.SecurityException("必须开启session支持");

            var value = HttpContext.Current.Session[FormsAuthentication.FormsCookieName] as string;
            if (value == null)
            {
                var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
                if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
                {
                    var tiket = FormsAuthentication.Decrypt(cookie.Value);
                    if (tiket != null)
                        HttpContext.Current.Session[FormsAuthentication.FormsCookieName] = value = tiket.UserData;
                }
                else
                {
                    throw new System.Security.SecurityException("错误的身份信息");
                }
            }

            if (!string.IsNullOrEmpty(value))
                return new Token(value);

            return null;
        }

        public void Clear()
        {
            var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (cookie != null)
            {
                cookie.CrossDomain();
                cookie.Expires = DateTime.Now.AddYears(-1);
                cookie.Value = null;
                HttpContext.Current.Response.Cookies.Add(cookie);
            }
            FormsAuthentication.SignOut();
        }
    }
}
